/*
 * Copyright (C) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#include "image_source.h"

namespace ImageKnifePro {
bool OptionData::GetString(std::string &result) const
{
    if ((DataType::STRING & availableType_) && (type_ == DataType::STRING)) {
        result = data_.str;
        return true;
    }
    return false;
}

std::string OptionData::ToString() const
{
    if ((DataType::STRING & availableType_) && (type_ == DataType::STRING)) {
        return data_.str;
    } else if ((DataType::NUMBER & availableType_) && (type_ == DataType::NUMBER)) {
        return std::to_string(data_.number);
    } else if ((DataType::RESOURCE & availableType_) && (type_ == DataType::RESOURCE)) {
        return "[Resource]: " + data_.resource.bundleName + "," +
               data_.resource.moduleName + "," + data_.resource.param + "," +  std::to_string(data_.resource.id);
    } else if (type_ == DataType::UNDEFINED) {
        return "[Undefined]";
    } else {
        return "[Object]";
    }
}

bool OptionData::GetNumber(int& result) const
{
    if ((DataType::NUMBER & availableType_) && (type_ == DataType::NUMBER)) {
        result = data_.number;
        return true;
    }
    return false;
}

bool OptionData::GetPixelMap(OH_PixelmapNative*& result) const
{
    if ((DataType::PIXELMAP & availableType_) && (type_ == DataType::PIXELMAP) && (data_.pixelMap != nullptr)) {
        result = data_.pixelMap;
        return true;
    }
    return false;
}

bool OptionData::MovePixelMap(OH_PixelmapNative *&result)
{
    if ((DataType::PIXELMAP & availableType_) && (type_ == DataType::PIXELMAP) && (data_.pixelMap != nullptr)) {
        result = data_.pixelMap;
        data_.pixelMap = nullptr;
        type_ = DataType::UNDEFINED;
        return true;
    }
    return false;
}

bool OptionData::GetResource(Resource &result) const
{
    if ((DataType::RESOURCE & availableType_) && (type_ == DataType::RESOURCE)) {
        result = data_.resource;
        return true;
    }
    return false;
}

void OptionData::SetString(std::string str)
{
    if (!(DataType::STRING & availableType_)) {
        return;
    }
    CleanData();
    new (&data_.str) std::string(str);
    type_ = DataType::STRING;
}

void OptionData::SetNumber(int number)
{
    if (!(DataType::NUMBER & availableType_)) {
        return;
    }
    CleanData();
    data_.number = number;
    type_ = DataType::NUMBER;
}

void OptionData::SetPixelMap(OH_PixelmapNative *pixelMap)
{
    if (!(DataType::PIXELMAP & availableType_)) {
        return;
    }
    CleanData();
    data_.pixelMap = pixelMap;
    type_ = DataType::PIXELMAP;
}

void OptionData::SetResource(Resource resource)
{
    if (!(DataType::RESOURCE & availableType_)) {
        return;
    }
    CleanData();
    new (&data_.resource) Resource(resource);
    type_ = DataType::RESOURCE;
}

bool OptionData::IsUndefined()
{
    if ((DataType::UNDEFINED & availableType_) && type_ == DataType::UNDEFINED) {
        return true;
    }
    return false;
}

void OptionData::SetUndefined()
{
    if (!(DataType::UNDEFINED & availableType_)) {
        return;
    }
    CleanData();
    type_ = DataType::UNDEFINED;
}

void OptionData::CleanData()
{
    if (type_ == DataType::UNDEFINED) {
        return;
    }
    switch (type_) {
        case DataType::STRING :
            data_.str.~basic_string();
            break;
        case DataType::RESOURCE :
            data_.resource.~Resource();
            break;
        case DataType::PIXELMAP :
            if (data_.pixelMap != nullptr) {
                OH_PixelmapNative_Release(data_.pixelMap);
                data_.pixelMap = nullptr;
            }
            break;
        default:
            return;
    }
}

DataType OptionData::GetType() const
{
    return type_;
}

OptionData::OptionData() : type_(DataType::UNDEFINED)
{
}

OptionData::~OptionData()
{
    CleanData();
}

OptionData::OptionData(unsigned int type) : type_(DataType::UNDEFINED), availableType_(type)
{
}

OptionData::ImageSrc::ImageSrc() : pixelMap(nullptr)
{
}

OptionData::ImageSrc::~ImageSrc()
{
}

ImageSource::ImageSource() : OptionData(DataType::STRING | DataType::PIXELMAP | DataType::RESOURCE)
{
}

ImageSource::ImageSource(std::string url) : ImageSource()
{
    SetString(url);
}

ImageSource::ImageSource(const char* url) : ImageSource(std::string(url))
{
}

ImageSource::ImageSource(OH_PixelmapNative *pixelMap) : ImageSource()
{
    SetPixelMap(pixelMap);
}

ImageSource::ImageSource(Resource resource) : ImageSource()
{
    SetResource(resource);
}

} // end of namespace